<!DOCTYPE html>
<html>
<head>
    <title>Physics Diagram</title>
    <style>
        body {
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            margin: 0;
            background-color: #f0f0f0;
        }
        canvas {
            border: 1px solid #ccc;
            background-color: #fff;
        }
    </style>
</head>
<body>
    <canvas id="physicsCanvas" width="550" height="450"></canvas>
    <script>
        const canvas = document.getElementById('physicsCanvas');
        const ctx = canvas.getContext('2d');

        // Helper function to draw an arrow
        function drawArrow(ctx, fromX, fromY, toX, toY, headLength) {
            const dx = toX - fromX;
            const dy = toY - fromY;
            const angle = Math.atan2(dy, dx);
            ctx.beginPath();
            ctx.moveTo(fromX, fromY);
            ctx.lineTo(toX, toY);
            ctx.lineTo(toX - headLength * Math.cos(angle - Math.PI / 6), toY - headLength * Math.sin(angle - Math.PI / 6));
            ctx.moveTo(toX, toY);
            ctx.lineTo(toX - headLength * Math.cos(angle + Math.PI / 6), toY - headLength * Math.sin(angle + Math.PI / 6));
            ctx.stroke();
        }

        // --- Parameters ---
        const R = 130; // Radius of the large circle
        const r = 65;  // Radius of the small circle
        const c = 55;  // Distance OO'

        const centerX = 270;
        const centerY = 220;
        const pointRadius = 3.5;
        const labelOffset = 15; // Vertical offset for labels P', P, O, O'

        // Coordinates
        const O = { x: centerX, y: centerY };
        const O_prime = { x: centerX + c, y: centerY };
        const P = { x: O.x - 90, y: centerY };
        const P_prime = { x: O.x - R - 50, y: centerY };

        // --- Drawing ---

        // 1. Draw the shaded area (sphere with cavity)
        ctx.fillStyle = 'rgba(220, 220, 220, 1)';
        ctx.beginPath();
        // Outer boundary (large circle)
        ctx.arc(O.x, O.y, R, 0, 2 * Math.PI, false);
        // Inner boundary (cavity, drawn counter-clockwise to create a hole)
        ctx.arc(O_prime.x, O_prime.y, r, 0, 2 * Math.PI, true);
        ctx.fill();

        // 2. Draw outlines and lines
        ctx.strokeStyle = 'black';
        ctx.lineWidth = 2;

        // Circle outlines
        ctx.beginPath();
        ctx.arc(O.x, O.y, R, 0, 2 * Math.PI);
        ctx.stroke();

        ctx.beginPath();
        ctx.arc(O_prime.x, O_prime.y, r, 0, 2 * Math.PI);
        ctx.stroke();

        // Horizontal axis
        ctx.beginPath();
        ctx.moveTo(P_prime.x - 20, centerY);
        ctx.lineTo(O_prime.x + r + 50, centerY);
        ctx.stroke();
        
        // Radius lines with arrows
        const arrowHeadLength = 10;
        
        // Arrow for R
        const angleR = 215 * Math.PI / 180; // Angle for the R vector
        const endR = { x: O.x + R * Math.cos(angleR), y: O.y + R * Math.sin(angleR) };
        drawArrow(ctx, O.x, O.y, endR.x, endR.y, arrowHeadLength);

        // Arrow for r
        const angler = -45 * Math.PI / 180; // Angle for the r vector
        const endr = { x: O_prime.x + r * Math.cos(angler), y: O_prime.y + r * Math.sin(angler) };
        drawArrow(ctx, O_prime.x, O_prime.y, endr.x, endr.y, arrowHeadLength);

        // 3. Draw points
        ctx.fillStyle = 'black';
        [P_prime, P, O, O_prime].forEach(point => {
            ctx.beginPath();
            ctx.arc(point.x, point.y, pointRadius, 0, 2 * Math.PI);
            ctx.fill();
        });

        // 4. Draw labels
        ctx.fillStyle = 'black';
        ctx.font = 'italic 22px Times New Roman';
        ctx.textAlign = 'center';
        ctx.textBaseline = 'bottom';
        
        // Labels for P', P, O, O'
        ctx.font = '22px Times New Roman';
        ctx.fillText("P'", P_prime.x, P_prime.y - labelOffset + 5);
        ctx.fillText("P", P.x, P.y - labelOffset + 5);
        ctx.fillText("O", O.x, O.y - labelOffset + 5);
        ctx.fillText("O'", O_prime.x, O_prime.y - labelOffset + 5);

        // Labels for R and r
        ctx.font = 'italic 22px Times New Roman';
        const labelR_pos = { x: O.x + R * 0.6 * Math.cos(angleR) - 10, y: O.y + R * 0.6 * Math.sin(angleR) + 10};
        ctx.fillText("R", labelR_pos.x, labelR_pos.y);

        const labelr_pos = { x: O_prime.x + r * 0.6 * Math.cos(angler) + 10, y: O_prime.y + r * 0.6 * Math.sin(angler) + 5};
        ctx.fillText("r", labelr_pos.x, labelr_pos.y);

        // Chinese text at the bottom
        ctx.font = '20px "SimSun", "Songti SC"'; // A common font for Chinese
        ctx.textAlign = 'center';
        ctx.textBaseline = 'bottom';
        ctx.fillText('习题 7-22 图', canvas.width / 2, canvas.height - 15);

    </script>
</body>
</html>